from django.http import JsonResponse, HttpResponse,StreamingHttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from celery.result import AsyncResult
from .tasks import generate_video
from .models import VideoHistory
from .serializers import VideoHistorySerializer
import json
import logging
import requests
import re
from urllib.parse import quote
logger = logging.getLogger(__name__)

@csrf_exempt
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def start_video_generation(request):
    try:
        data = json.loads(request.body)
        prompt = data.get('prompt')
        quality = data.get('quality', 'quality')  # 默认为 'quality'
        fps = data.get('fps', 30)  # 默认为 30
        if not prompt:
            return JsonResponse({'error': '提示词为必填项'}, status=400)
        task = generate_video.delay(request.user.id, prompt, mode='text', image_url=None, confirmed=False,
                                    quality=quality, fps=fps)
        logger.info(f"任务 {task.id} 已提交，状态为 WAITING，用户 {request.user.id}")
        return JsonResponse({'task_id': task.id, 'status': 'WAITING'})
    except json.JSONDecodeError:
        logger.error("start_video_generation 中的 JSON 无效")
        return JsonResponse({'error': '无效的 JSON'}, status=400)
    except Exception as e:
        logger.error(f"任务提交失败: {str(e)}")
        return JsonResponse({'error': f'任务提交失败: {str(e)}'}, status=500)


@csrf_exempt
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def start_image_video_generation(request):
    try:
        data = json.loads(request.body)
        prompt = data.get('prompt')
        image_url = data.get('image_url')
        quality = data.get('quality', 'quality')  # 默认为 'quality'
        fps = data.get('fps', 30)  # 默认为 30
        if not prompt or not image_url:
            return JsonResponse({'error': '提示词和图片 URL 为必填项'}, status=400)
        task = generate_video.delay(request.user.id, prompt, mode='image', image_url=image_url, confirmed=False,
                                    quality=quality, fps=fps)
        logger.info(f"任务 {task.id} 已提交，状态为 WAITING，图片视频，用户 {request.user.id}")
        return JsonResponse({'task_id': task.id, 'status': 'WAITING'})
    except json.JSONDecodeError:
        logger.error("start_image_video_generation 中的 JSON 无效")
        return JsonResponse({'error': '无效的 JSON'}, status=400)
    except Exception as e:
        logger.error(f"任务提交失败: {str(e)}")
        return JsonResponse({'error': f'任务提交失败: {str(e)}'}, status=500)


@csrf_exempt
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def start_frames_video_generation(request):
    try:
        data = json.loads(request.body)
        prompt = data.get('prompt')
        image_url = data.get('image_url')
        quality = data.get('quality', 'quality')  # 默认为 'quality'
        fps = data.get('fps', 30)  # 默认为 30
        if not prompt or not image_url or not isinstance(image_url, list) or len(image_url) != 2:
            return JsonResponse({'error': '提示词和图片 URL（包含2个URL的列表）为必填项'}, status=400)
        task = generate_video.delay(request.user.id, prompt, mode='frames', image_url=image_url, confirmed=False,
                                    quality=quality, fps=fps)
        logger.info(f"任务 {task.id} 已提交，状态为 WAITING，首尾帧视频，用户 {request.user.id}")
        return JsonResponse({'task_id': task.id, 'status': 'WAITING'})
    except json.JSONDecodeError:
        logger.error("start_frames_video_generation 中的 JSON 无效")
        return JsonResponse({'error': '无效的 JSON'}, status=400)
    except Exception as e:
        logger.error(f"任务提交失败: {str(e)}")
        return JsonResponse({'error': f'任务提交失败: {str(e)}'}, status=500)


@csrf_exempt
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def confirm_video_generation(request):
    try:
        data = json.loads(request.body)
        task_id = data.get('task_id')
        if not task_id:
            logger.error("任务 ID 为必填项")
            return JsonResponse({'error': '任务 ID 为必填项'}, status=400)
        task = AsyncResult(task_id)
        logger.info(f"确认任务 {task_id}，状态: {task.state}，结果: {task.result}")
        if task.state not in ['PENDING', 'SUCCESS'] or not task.result or task.result.get('status') != 'WAITING':
            logger.warning(f"任务 {task_id} 不在 WAITING 状态: 状态={task.state}, 结果={task.result}")
            return JsonResponse({'error': '任务不在 WAITING 状态'}, status=400)
        prompt = task.result.get('prompt')
        image_url = task.result.get('image_url', None)
        mode = task.result.get('mode', 'text')
        quality = task.result.get('quality', 'quality')  # 从任务结果中获取 quality
        fps = task.result.get('fps', 30)  # 从任务结果中获取 fps
        if not prompt:
            logger.error(f"任务 {task_id} 结果中未找到提示词")
            return JsonResponse({'error': '任务结果中未找到提示词'}, status=400)
        new_task = generate_video.delay(request.user.id, prompt, mode, image_url, confirmed=True, quality=quality,
                                        fps=fps)
        logger.info(f"新的任务 {new_task.id} 已创建，用于确认生成，用户 {request.user.id}")
        return JsonResponse({'task_id': new_task.id, 'status': 'PROCESSING'})
    except json.JSONDecodeError:
        logger.error("confirm_video_generation 中的 JSON 无效")
        return JsonResponse({'error': '无效的 JSON'}, status=400)
    except Exception as e:
        logger.error(f"确认失败: {str(e)}")
        return JsonResponse({'error': f'确认失败: {str(e)}'}, status=400)


@csrf_exempt
@api_view(['GET'])
def get_task_status(request, task_id):
    try:
        task = AsyncResult(task_id)
        logger.info(f"检查任务 {task_id} 的状态: 状态={task.state}, 结果={task.result}")
        if task.state in ['PENDING', 'PROCESSING', 'WAITING', 'SUCCESS']:
            return JsonResponse({'status': task.state, 'result': task.result, 'error': None})
        elif task.state == 'FAILURE':
            return JsonResponse({'status': task.state, 'result': None, 'error': str(task.result)})
        else:
            logger.warning(f"任务 {task_id} 的状态未知: {task.state}")
            return JsonResponse({'status': task.state, 'result': None, 'error': '未知任务状态'})
    except Exception as e:
        logger.error(f"任务状态检查失败，任务 {task_id}: {str(e)}")
        return JsonResponse({'error': f'任务状态检查失败: {str(e)}'}, status=500)

@csrf_exempt
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def proxy_video(request):
    if request.method == 'GET':
        video_url = request.GET.get('url')
        is_download = request.GET.get('download', 'false').lower() == 'true'

        if not video_url:
            logger.error(f"用户 {request.user.id} 请求代理视频失败: 缺少视频 URL")
            return JsonResponse({'error': '视频 URL 为必填项'}, status=400)

        # 验证 URL 格式
        if not re.match(r'^https?://', video_url):
            logger.error(f"用户 {request.user.id} 请求代理视频失败: 无效的视频 URL {video_url}")
            return JsonResponse({'error': '无效的视频 URL'}, status=400)

        try:
            # 查询 VideoHistory 获取视频元数据（用于动态文件名）
            video_history = VideoHistory.objects.filter(user=request.user, video_url=video_url).first()
            filename = 'generated_video.mp4'
            if video_history:
                # 使用 prompt 和时间戳生成文件名
                prompt_snippet = video_history.prompt[:30].replace(' ', '_') if video_history.prompt else 'video'
                timestamp = video_history.created_at.strftime('%Y%m%d_%H%M%S')
                filename = f"{prompt_snippet}_{timestamp}.mp4"

            # 转发 Range 头（用于播放时的流式传输）
            headers = {}
            if 'Range' in request.headers and not is_download:
                headers['Range'] = request.headers['Range']

            response = requests.get(video_url, stream=True, headers=headers, timeout=10)
            response.raise_for_status()

            content_type = response.headers.get('Content-Type', 'video/mp4')
            headers = {
                'Content-Type': content_type,
            }

            # 如果是下载请求，添加 Content-Disposition 头
            if is_download:
                headers['Content-Disposition'] = f'attachment; filename="{quote(filename)}"'

            # 处理范围请求（用于播放）
            if response.status_code == 206 and not is_download:
                headers['Content-Range'] = response.headers.get('Content-Range')
                headers['Accept-Ranges'] = 'bytes'

            # 流式传输内容
            def stream_content():
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        yield chunk

            logger.info(f"用户 {request.user.id} 成功代理视频: {video_url}, 下载: {is_download}")
            return StreamingHttpResponse(
                stream_content(),
                status=response.status_code,
                headers=headers
            )
        except requests.RequestException as e:
            logger.error(f"用户 {request.user.id} 代理视频失败: {str(e)}, URL: {video_url}")
            return JsonResponse({'error': f'视频代理失败: {str(e)}'}, status=500)
    return JsonResponse({'error': '方法不允许'}, status=405)


@csrf_exempt
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def video_history(request):
    try:
        histories = VideoHistory.objects.filter(user=request.user)
        serializer = VideoHistorySerializer(histories, many=True)
        return JsonResponse({'code': 200, 'data': serializer.data})
    except Exception as e:
        logger.error(f"获取视频历史记录失败: {str(e)}")
        return JsonResponse({'error': f'获取视频历史记录失败: {str(e)}'}, status=500)


from django.shortcuts import render

# Create your views here.
